package com.tansun.easycare.rule.ruleflow.web;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.tansun.easycare.rule.common.enums.RuleModelTypeFileEnum;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.github.pagehelper.PageInfo;
import com.tansun.easycare.core.utils.ResponseTable;
import com.tansun.easycare.move.RuleCollectionVo;
import com.tansun.easycare.move.RuleCollectionVos;
import com.tansun.easycare.move.RuleFlowVo;
import com.tansun.easycare.move.RuleFlowVos;
import com.tansun.easycare.move.RuleSetVo;
import com.tansun.easycare.move.RuleVo;
import com.tansun.easycare.rule.codeblock.entity.RuleCodeblock;
import com.tansun.easycare.rule.codeblock.service.RuleCodeblockService;
import com.tansun.easycare.rule.common.Constant;
import com.tansun.easycare.rule.common.JsonMessage;
import com.tansun.easycare.rule.common.ResMessage;
import com.tansun.easycare.rule.common.RuleBaseController;
import com.tansun.easycare.rule.common.model.ResponseVO;
import com.tansun.easycare.rule.common.model.SelectEditorVo;
import com.tansun.easycare.rule.common.model.SelectModelVo;
import com.tansun.easycare.rule.exception.BizException;
import com.tansun.easycare.rule.ruleflow.entity.RuleFlow;
import com.tansun.easycare.rule.ruleflow.model.RuleFlowModel;
import com.tansun.easycare.rule.ruleflow.model.RuleFlowVO;
import com.tansun.easycare.rule.ruleflow.model.RuleNextNodeInfo;
import com.tansun.easycare.rule.ruleflow.model.RuleNextTreeNode;
import com.tansun.easycare.rule.ruleflow.service.RuleFlowService;
import com.tansun.easycare.rule.rulegroup.entity.RuleGroup;
import com.tansun.easycare.rule.rulegroup.service.RuleGroupService;
import com.tansun.easycare.rule.rulemange.entity.RuleManage;
import com.tansun.easycare.rule.rulemange.model.RuleManageVO;
import com.tansun.easycare.rule.rulemange.service.RuleManageService;
import com.tansun.easycare.rule.ruleversion.entity.RuleVersioninfo;
import com.tansun.rule.common.RuleModelTypeEnum;
import com.tansun.rule.utils.JavaUnmarshaller;
import com.tansun.rule.utils.StringUtils;

/**
 * 规则流 控制器
 *
 * @author ZengWenfeng
 */
@RestController
@RequestMapping(value = "/ruleProj/ruleFlow")
public class RuleFlowController extends RuleBaseController {
    public final static String MODE_ADD = "1";
    public final static String MODE_MOD = "2";
    public final static String MODE_VIEW = "3";

    @Autowired
    private RuleFlowService ruleFlowService;
    @Autowired
    private RuleManageService ruleManageService;
    @Autowired
    private RuleGroupService ruleGroupService;
    @Autowired
    private RuleCodeblockService ruleCodeblockService;

    /**
     * 跳转index页面
     *
     * @param projectCode 项目编码
     * @param map         ModelMap
     * @return String 页面地址
     */
    @RequestMapping("index")
    public ResponseTable<RuleManageVO> index(@RequestBody RuleManageVO param) throws Exception {
        PageInfo<RuleManageVO> pageInfo = this.ruleManageService.findRuleManageVO(param.getPage(), param);
        ResponseTable<RuleManageVO>  resVo  = new  ResponseTable<RuleManageVO>(pageInfo);
        return resVo;
    }
    
    
    @RequestMapping("findAllPublishVersion")
    public ResponseVO findAllNewPublishVersion(@RequestBody RuleVersioninfo ruleVersionInfo) {
    	List<SelectEditorVo> list =this.ruleFlowService.getAllNewPublishVersion(ruleVersionInfo);
    	ResponseVO  res  = new  ResponseVO();
    	res.setData(list);
    	return  res;
    }
    

    /**
     * 以新增模式打开流程设计器
     *
     * @param model 规则流Model对象
     * @param map   ModelMap
     * @return String 页面地址
     */
    @RequestMapping("openRuleFlowDetail")
    public ResponseVO openRuleFlowDetail(@RequestBody RuleFlowModel model) throws Exception {
    	ResponseVO  res = new ResponseVO();
        Map<String,String> map  = new HashMap<>();
        RuleFlowVO  ruleFlow = ruleFlowService.getRuleFlowData(model, map);
        RuleManage manage = ruleManageService.getById(model.getManageId());
        if (manage == null) {
        	manage = new  RuleManage();
        	manage.setProjectCode(model.getProjectCode());
        } 	
        ruleFlow.setRuleManage(manage);
        ruleFlow.setRankRelationId(model.getRankRelationId());
        res.setData(ruleFlow);
        
        return res;
    }

    /**
     * 新增规则流
     *
     * @param model 规则流Model对象
     * @return ResMessage 消息对象
     */
    @RequestMapping("saveOrUpdate")
    public 
    ResponseVO saveOrUpdate(@RequestBody RuleFlowModel model) throws Exception {
    	ResponseVO message = new ResponseVO();
        try {

            Integer num = this.ruleFlowService.countListFindName(model);
            if (num != null && num>0) {
                message.setStatus(ResponseVO.ERROR);
                message.setDescription("变量名称重复，请使用其他有效名称");
                return message;
            }
            ruleFlowService.saveOrUpdate(model);
        } catch (Exception e) {
            e.printStackTrace();
            message.setDescription(e.getMessage());
            message.setStatus(ResponseVO.ERROR);;
        }
        return message;
    }
    
    /**
     * 显示java代码
     *
     * @param model 规则流Model对象
     * @return ResMessage 消息对象
     */
    @RequestMapping("showJavaCode")
    public @ResponseBody
    ResMessage showJavaCode(@RequestBody RuleFlowModel model) throws Exception {
        ResMessage message = new ResMessage();
        try {
        	String javacode = ruleFlowService.showJavaCode(model);
        	message.setMsg(javacode);
        	message.setCode("success");
        } catch (Exception e) {
            e.printStackTrace();
            message.setCode("failure");
        }
        return message;
    }

    /**
     * 删除规则流
     *
     * @param model 规则流Model对象
     * @return ResMessage 消息对象
     */
    @RequestMapping("delRuleFlowModel")
    public @ResponseBody
    ResMessage delRuleFlowModel(HttpServletRequest request, HttpServletResponse response, @ModelAttribute RuleFlowModel model) throws Exception {
        ResMessage message = new ResMessage();
        return message;
    }

    /**
     * 发布规则流
     *
     * @param flowId 规则流ID
     * @return ResMessage 消息对象
     */
    @RequestMapping("publishRuleFlowModel")
    public @ResponseBody
    ResMessage publishRuleFlowModel(String flowId) throws Exception {
        ResMessage message = new ResMessage();
        try {
            ruleManageService.setRuleBaseService(ruleFlowService);
            ruleManageService.publicRule(flowId);
        } catch (Exception e) {
        	message.setMsg(e.getMessage());
            message.setCode("failure");
            log.error("规则流发布出错", e);
        }
        return message;
    }

    /**
     * 跳转版本选择页面
     *
     * @param model 规则流Model对象
     * @return String 页面地址
     */
    @RequestMapping("openSelectVersionDlg")
    public String openSelectVersionDlg(HttpServletRequest request, HttpServletResponse response, @ModelAttribute RuleFlowModel model, ModelMap map) throws Exception {
//		List<RuleFlowVersionVo> list = ruleFlowService.getRuleFlowVersion(model);
//		map.put("list", list);
        return "rule/ruleflow/selectVersionDlg";
    }

    /**
     * 条件选择对话框
     *
     * @param model RuleFlowModel{code:txtContent0, data:al3333#vavgq1111#内容,
     *              project:myRuleProject111}
     * @param map   ModelMap
     * @return String 页面地址
     */
    @RequestMapping("openConditionTreeDlg")
    public String openConditionTreeDlg(HttpServletRequest request, HttpServletResponse response, @ModelAttribute RuleFlowModel model, ModelMap map) throws Exception {
        //RuleFlowModel{code:txtContent0, data:al3333#vavgq1111#内容, project:myRuleProject111}
        //由ruleFlowDesignerDlg.jsp前面页面传入conditionTreeDlg.jsp
//		map.put("paramProjectCode", model.getProject());
//		map.put("paramData", model.getData());
        map.put("paramTargeId", model.getCode());

        return "rule/ruleflow/conditionTreeDlg";
    }

    /**
     * 条件选择对话框
     *
     * @param projectCode 项目编码
     * @param context     节点数据
     * @param clickId     单击节点
     * @param map         ModelMap
     * @return String 页面地址
     */
    @RequestMapping("getConditionNodeInfo")
    public String getConditionNodeInfo(HttpServletRequest request, String projectCode, String context, String clickId, ModelMap map) throws Exception {
        //
        map.put("paramProjectCode", projectCode);
        map.put("paramData", context);
        map.put("paramTargeId", clickId);
        return "rule/ruleflow/conditionTreeDlg";
    }

    /**
     * 以查看模式打开流程设计器
     *
     * @param model 规则流Model对象
     * @param map   ModelMap
     * @return String 页面地址
     */
    @RequestMapping("openViewDlg")
    public String openViewDlg(HttpServletRequest request, HttpServletResponse response, String code,String version,  String temp,String rankRelationId) throws Exception {
//		ruleFlowService.openViewDlg(model, map);
    	RuleManage manage = ruleManageService.getById(code);
    	if(manage==null){
    		manage = ruleManageService.findByCode(code, this.getCurrProjectCode());
    	}
    	RuleFlowModel model = new RuleFlowModel();
    	model.setManageId(manage.getId());
    	model.setProjectCode(manage.getProjectCode());
    	if(StringUtils.isNoneBlank(version)){
    		model.setVersion(version);
    	}else{
    		model.setVersion(manage.getVersion());
    		if("1".equals(temp)) {
    			model.setVersion(manage.getActiveVersion());
    		}
    	}
    	Map<String,String> map  = new HashMap<>();
        ruleFlowService.getRuleFlowData(model, map);
        //map.put("ruleflow", manage);
        map.put("rankRelationId", rankRelationId);
        return "rule/ruleflow/ruleFlowDesignerDlg";
    }

    /**
     * 获取所有版本
     *
     * @param model 规则流Model对象
     * @param map   ModelMap
     * @return String 页面地址
     */
    @RequestMapping("getRuleFlowVersion")
    public String getRuleFlowVersion(HttpServletRequest request, HttpServletResponse response, @ModelAttribute RuleFlowModel model, ModelMap map) throws Exception {
//		List<RuleFlowVersionVo> list = ruleFlowService.getRuleFlowVersion(model);
//		map.put("code", model.getCode());
//		map.put("list", list);
        return "rule/ruleflow/selectVersionDlg";
    }

    /**
     * 回退规则流
     *
     * @param model 规则流Model对象
     * @param map   ModelMap
     * @return ResMessage 消息对象
     */
    @RequestMapping("revertRuleFlowModel")
    public @ResponseBody
    ResMessage revertRuleFlowModel(HttpServletRequest request, HttpServletResponse response, @ModelAttribute RuleFlowModel model) throws Exception {
//		ResMessage message = ruleFlowService.revertRuleFlowModel(model);
        ResMessage message = new ResMessage();
        return message;
    }

    /**
     * 获取规则流模型信息
     *
     * @param code    规则流编码
     * @param version 版本
     * @return JsonMessage 消息对象
     */
    @RequestMapping("getRuleFlowModel")
    public @ResponseBody
    JsonMessage getRuleFlowModel(String code, String version) throws Exception {
        RuleFlow ruleFlow = new RuleFlow();
        ruleFlow.setManageId(code);
        ruleFlow.setVersion(version);
        List<RuleFlow> list = this.ruleFlowService.findList(ruleFlow);
        if (list == null || list.size() == 0) {
            throw new BizException("E-000600");
        }
        RuleFlow ruleFl = list.get(0);

        JsonMessage ret = new JsonMessage();
        ret.setData(ruleFl.getRuleflowInfo());
        return ret;
    }

    @Override
    public void setRuleBizService() {
        // TODO Auto-generated method stub
        super.setRuleBaseService(this.ruleFlowService);
    }

    @RequestMapping("moveFlowToDB")
    public @ResponseBody JsonMessage moveFlowToDB(String basePath,String projectCode) throws Exception {
        String xml_file = basePath+ "\\" +projectCode+"\\ruleFlow";
        RuleFlowModel model = null;
        RuleFlowVos vos = (RuleFlowVos) JavaUnmarshaller.xml2Bom(xml_file + "\\ruleFlow.xml", RuleFlowVos.class);
        for (RuleFlowVo vo : vos.getRuleFlowVo()) {
            model = new RuleFlowModel();
            model.setName(vo.getName());
            model.setCode(vo.getCode());
            model.setProjectCode(this.getCurrProjectCode());
            com.tansun.easycare.move.RuleFlowModel m = (com.tansun.easycare.move.RuleFlowModel) JavaUnmarshaller.xml2Bom(xml_file + "\\" + vo.getCode() + "\\" + vo.getVersion() + "\\model.xml", com.tansun.easycare.move.RuleFlowModel.class);
            model.setRuleflowInfo(m.getData());
            ruleFlowService.saveOrUpdate(model);
        }
        return new JsonMessage();
    }

    @RequestMapping("moveRuleSetToDB")
    public @ResponseBody
    JsonMessage moveRuleSetToDB(String basePath,String projectCode) throws Exception {
        String xml_file =  basePath+ "\\" +projectCode+"\\ruleGroup";
        Object obj = JavaUnmarshaller.xml2Bom(xml_file + "\\ruleGroup.xml", RuleCollectionVos.class);
        if (obj != null) {
            RuleCollectionVos rcvs = (RuleCollectionVos) obj;
            List<RuleCollectionVo> rcvsList = rcvs.getRuleCollectionVo();
            List<RuleCollectionVo> resultList = new ArrayList<RuleCollectionVo>();
            if (rcvsList != null && rcvsList.size() > 0) {
                for (RuleCollectionVo vo : rcvsList) {
                    if (!"0".equals(vo.getState())) {
                        resultList.add(vo);
                    }
                }
            }
            RuleManage rcv = null;
            for (RuleCollectionVo vo : resultList) {
                rcv = new RuleManage();
                rcv.setModelType(RuleModelTypeEnum.PolicyRuleGroup.code);
                rcv.setProjectCode(this.getCurrProjectCode());
                rcv.setCountSalience(Constant.FIRST_SALIENCE);
                rcv.setName(vo.getName());
                rcv.setCode(vo.getCode());
                ruleManageService.saveOrUpdate(rcv);

                String rcCode = vo.getCode();
                String rcCodeStr = StringUtils.isBlank(rcCode) ? "" : ("/" + vo.getCode());
                String path = xml_file + "/" + rcCodeStr;//+"/ruleSet.xml";
                if (StringUtils.isNotBlank(vo.getVersion())) {
                    if (!vo.getVersion().startsWith("v")) {
                        path = path + "/v" + vo.getVersion() + "/ruleSet.xml";
                    } else {
                        path = path + "/" + vo.getVersion() + "/ruleSet.xml";
                    }
                } else {
                    path = path + "/ruleSet.xml";
                }
                RuleSetVo rc = (RuleSetVo) JavaUnmarshaller.xml2Bom(path, RuleSetVo.class);
                RuleGroup groupItem = null;
                for (RuleVo r : rc.getRules()) {
                    groupItem = new RuleGroup();
                    BeanUtils.copyProperties(groupItem, r);
                    groupItem.setManageId(rcv.getId());
                    groupItem.setId(null);
                    groupItem.setEvals(groupItem.getEvals().replaceAll("ruleweb-project", "rule-platform"));
                    groupItem.setFacts(groupItem.getFacts().replaceAll("ruleweb-project", "rule-platform"));
                    groupItem.setActions(groupItem.getActions().replaceAll("ruleweb-project", "rule-platform"));

                    groupItem.setEvals(groupItem.getEvals().replaceAll("static", "static/rule"));
                    groupItem.setFacts(groupItem.getFacts().replaceAll("static", "static/rule"));
                    groupItem.setActions(groupItem.getActions().replaceAll("static", "static/rule"));

                    this.ruleGroupService.saveOrUpdate(groupItem);
                }
            }
        }

        return new JsonMessage();
    }
    
    @RequestMapping("findTreeNextNode")
    public ResponseVO  findTreeNextNode(@RequestBody RuleNextNodeInfo  nextInfo) {
    	ResponseVO  res  = new ResponseVO();
    	List<RuleNextTreeNode>  list=null;
    	try {		
    	  	list =this.ruleFlowService.findTreeClassType(nextInfo.getProjectCode(), nextInfo.getTreeCode());
    	}catch(Exception e) {
    		
    	}
    	res.setData(list);
    	return res;
    }
    
    @RequestMapping("findNextModel")
    public  ResponseVO  findNextModel(@RequestBody  RuleManage  ruleManage) {
    	ResponseVO  res  = new  ResponseVO();
    	String  modelType  = ruleManage.getModelType();
    	try {
    		  String  projectCode  =  ruleManage.getProjectCode();	
	          RuleManage  ruleInfo  = new  RuleManage();
	          ruleInfo.setProjectCode(projectCode);
	          ruleInfo.setModelType(modelType);
	          ruleInfo.setActiveFlag("1");	
	     	   List<SelectModelVo> retList   = new  ArrayList<>();	
	     	   SelectModelVo  seleModelVo  = null;
	     	   if ("".equals(modelType)) {
	     		   res.setData(retList);
	     		   return res;
	     	   }
	     	   if (RuleModelTypeEnum.FunctionParam.code.equals(modelType)) {
	               RuleCodeblock funcentity = new RuleCodeblock();
	               funcentity.setProjectCode(projectCode);
	               List<RuleCodeblock> funcList = ruleCodeblockService.findParamFuncList(funcentity);
	               for (RuleCodeblock obj : funcList) {
	                   String value = obj.getFunctionName();
	                   String name = obj.getModelName();
		    		   seleModelVo  = new  SelectModelVo();
		    		   seleModelVo.setCode(value);
		    		   seleModelVo.setName(name);
	                   retList.add(seleModelVo);
	               }
	
	     	   }else if ("flowEnd".equals(modelType)) {
	    		   seleModelVo  = new  SelectModelVo();
	    		   seleModelVo.setCode("");
	    		   seleModelVo.setName("");
	    		   retList.add(seleModelVo);
	     	   }
	     	   else {   
		    	   List<RuleManage>  list  =	this.ruleManageService.findList(ruleInfo);
		    	   java.util.Iterator<RuleManage> iter  =null;
		    	   RuleManage  rMan =null;
		    	   for ( iter=list.iterator();iter.hasNext();) {
		    		   rMan = iter.next();
		    		   if (rMan.getCode().equals(ruleManage.getCode())) {
		    		
		    		   }else {
			    		   seleModelVo  = new  SelectModelVo();
			    		   seleModelVo.setCode(rMan.getCode());
			    		   seleModelVo.setName(rMan.getName());
			    		   retList.add(seleModelVo);
		    		   }
		    	   }
	     	   }

	    	   res.setData(retList);
    	}catch (Exception e) {
    		res.setStatus(ResponseVO.ERROR);
			res.setDescription(e.getMessage());
		}
    	return res;
    	
    }
    
}